package cn.jx.cjm.security.support;

import cn.jx.cjm.common.aop.annotation.Lockable;
import cn.jx.cjm.common.base.BaseRequest;
import cn.jx.cjm.common.enums.BizExceptionEnum;
import cn.jx.cjm.common.exception.BizException;
import cn.jx.cjm.common.util.BeanUtils;
import cn.jx.cjm.common.util.ParentEntityUtils;
import cn.jx.cjm.security.dto.request.SysDepartmentRequest;
import cn.jx.cjm.security.dto.response.SysDepartmentResponse;
import cn.jx.cjm.security.entity.SysDepartment;
import cn.jx.cjm.security.service.ISysDepartmentService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;


/**
 * 部门 业务处理层
 *
 * @author James Chen right_way@foxmail.com
 * @since 2020-10-16
 */
@Service
public class SysDepartmentSupportService {

    private final static String CACHE_SYS_DEPARTMENT = "CACHE:SYS_DEPARTMENT";
    private final static String SPLIT = "-";

    @Autowired
    private ISysDepartmentService sysDepartmentService;
    @Autowired
    private SysDepartmentSupportService sysDepartmentSupportService;

    /**
     * 部门 列表
     *
     * @param request .
     * @return .
     */
    public List<SysDepartmentResponse> list(SysDepartmentRequest request) {
        return options(null == request ? null : request.getParentId());
    }

    //@Cacheable(cacheNames = CACHE_SYS_DEPARTMENT, key = "'ALL'")
    public List<SysDepartmentResponse> listAll() {
        QueryWrapper<SysDepartment> queryWrapper = new BaseRequest<SysDepartment>().getQueryWrapper(SysDepartment.class);
        List<SysDepartment> list = sysDepartmentService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>(0);
        }
        List<SysDepartmentResponse> responseList = new ArrayList<>();
        for (SysDepartment temp : list) {
            SysDepartmentResponse response = new SysDepartmentResponse();
            BeanUtils.copyPropertiesIgnoreNull(temp, response);
            responseList.add(response);
        }
        return responseList;
    }

    /**
     * 部门 下拉框
     *
     * @return
     */
    public List<SysDepartmentResponse> options(Integer parentId) {
        List<SysDepartmentResponse> responseList = sysDepartmentSupportService.listAll();
        if (CollectionUtils.isEmpty(responseList)) {
            return new ArrayList<>(0);
        }
        ParentEntityUtils<SysDepartmentResponse> treeUtils = new ParentEntityUtils<>(responseList);
        return treeUtils.getTree(parentId);
    }

    //@Cacheable(cacheNames = CACHE_SYS_DEPARTMENT, unless="#result == null", key = "#id")
    public SysDepartmentResponse getOne(Integer id) {
        SysDepartment temp = sysDepartmentService.getById(id);
        if (null == temp) {
            return null;
        }
        SysDepartmentResponse result = new SysDepartmentResponse();
        BeanUtils.copyPropertiesIgnoreNull(temp, result);
        return result;
    }

    //@CacheEvict(cacheNames = CACHE_SYS_DEPARTMENT, allEntries = true)
    @Lockable(lockName = CACHE_SYS_DEPARTMENT + "_LOCK", key = "#request.parentId + '-' + #request.name")
    public void save(SysDepartmentRequest request) {
        SysDepartment temp = new SysDepartment();
        BeanUtils.copyPropertiesIgnoreNull(request, temp);
        temp.setCreateTime(LocalDateTime.now());
        sysDepartmentService.save(temp);
        if (null != request.getParentId()) {
            SysDepartment department = sysDepartmentService.getById(temp.getParentId());
            temp.setRule(department.getRule() + SPLIT + temp.getId());
        } else {
            temp.setRule("" + temp.getId());
        }
        sysDepartmentService.updateById(temp);
    }

    //@CacheEvict(cacheNames = CACHE_SYS_DEPARTMENT, allEntries = true)
    public void update(SysDepartmentRequest request) {
        SysDepartment temp = new SysDepartment();
        BeanUtils.copyPropertiesIgnoreNull(request, temp);
        if (null != request.getParentId()) {
            SysDepartment department = sysDepartmentService.getById(temp.getParentId());
            temp.setRule(department.getRule() + SPLIT + temp.getId());
        } else {
            temp.setRule("" + temp.getId());
        }
        sysDepartmentService.updateById(temp);
    }

    //@CacheEvict(cacheNames = CACHE_SYS_DEPARTMENT, allEntries = true)
    @Transactional(rollbackFor = {BizException.class}, propagation = Propagation.REQUIRED)
    public void remove(Integer id) {
        List<SysDepartmentResponse> responseList = listAll();
        if (!CollectionUtils.isEmpty(responseList)) {
            ParentEntityUtils<SysDepartmentResponse> treeUtils = new ParentEntityUtils<>(responseList);
            Set<Integer> ids = treeUtils.getChildIds(id);
            ids.add(id);
            sysDepartmentService.removeByIds(ids);
        }
    }

}